package com.dnjn.happiness.common.tenant;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @author amber
 * @version 1.0
 * @date 2024/5/17 17:13
 **/
@Aspect
@Slf4j
@Component
public class TenantIgnoreAspect {

    /**
     * 切入点
     */
    @Pointcut("@within(com.dnjn.happiness.common.tenant.TenantIgnore) ||@annotation(com.dnjn.happiness.common.tenant.TenantIgnore)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        try {
            Class<?> targetClass = point.getTarget().getClass();
            TenantIgnore classTenantIgnore = targetClass.getAnnotation(TenantIgnore.class);
            MethodSignature signature = (MethodSignature) point.getSignature();
            Method method = signature.getMethod();
            TenantIgnore methodTenantIgnore = method.getAnnotation(TenantIgnore.class);

            //判断类上是否有注解
            boolean isClassAnnotated = AnnotationUtils.isAnnotationDeclaredLocally(TenantIgnore.class, targetClass);
            //判断方法上是否有注解
            boolean isMethodAnnotated = Objects.nonNull(methodTenantIgnore);

            //如果类上有
            if (isClassAnnotated) {
                TenantContext.set(classTenantIgnore.isIgnore());
            }
            //如果方法上有 以方法上的为主
            if (isMethodAnnotated) {
                TenantContext.set(methodTenantIgnore.isIgnore());
            }
            Object result = point.proceed();
            return result;
        } finally {
            TenantContext.clear();
        }
    }

}